import { createElements, define, itag } from "../itag/index.js";
import { DATA_TYPE_LENGTH_MAP } from "../types.js";
import type { IRequestFieldElement } from "./IFieldElement.js";
import type { NumberRequestFieldOption } from "./RequestOption.js";
import * as styles from "./styles.js";

/**
 * 数值组元素
 */
export class NumberRequestFieldElement extends HTMLElement implements IRequestFieldElement {
    readonly #elms = createElements({
        container: "div",
        inputs: "div",
        name: "div",
        range: "div",
    });

    #inputs: HTMLInputElement[] = [];

    #length: number = 1;

    #option: NumberRequestFieldOption | null = null;

    #value: number = 0;

    constructor() {
        super();
        const sr = this.attachShadow({ mode: "open" });
        sr.adoptedStyleSheets.push(styles.sheet);

        itag`
${sr}
    ${this.#elms.container} .container
        ${this.#elms.inputs} 
        ${this.#elms.name}  .${styles.name}
        ${this.#elms.range} .${styles.range}
`;

        this.#update();
    }

    get option(): NumberRequestFieldOption | null {
        return this.#option;
    }

    set option(value: NumberRequestFieldOption | null) {
        if (value === this.#option) {
            return;
        }
        this.#option = value;
        if (value === null) {
            return;
        }
        this.#elms.name.textContent = value.name;
        this.#value = value.value ?? 0;
        if (value.readonly) {
            for (const input of this.#inputs) {
                input.readOnly = true;
            }
        } else {
            for (const input of this.#inputs) {
                input.removeAttribute("readonly");
            }
        }
        this.#update();
    }

    get name(): string {
        return this.#option?.name ?? "";
    }

    /**
     * 获取数据
     */
    data(): number[] {
        const data = [];
        for (const input of this.#inputs) {
            data.push(parseInt(input.value, 16));
        }

        return data;
    }

    /**
     * 获取长度
     */
    byteLength(): number {
        return this.#length;
    }

    /**
     * 设置起始位置
     */
    setBegin(begin: number) {
        this.#elms.range.textContent = `${begin} - ${begin + DATA_TYPE_LENGTH_MAP[this.#option?.kind ?? "u8"]}`;
        this.#update();
    }

    /**
     * 更新界面
     */
    #update() {
        this.#inputs = [];
        this.#elms.inputs.innerHTML = "";
        this.#length = DATA_TYPE_LENGTH_MAP[this.#option?.kind ?? "u8"];
        for (let i = 0; i < this.#length; i++) {
            const input = document.createElement("input");
            input.classList.add(styles.input, styles.number);

            const value = (this.#value >> (i * 8)) & 0xff;
            input.value = value.toString(16).padStart(2, "0");
            input.type = "text";
            input.maxLength = 3;
            if (this.#option?.readonly === true) {
                input.readOnly = true;
            }
            input.addEventListener("focus", () => {
                input.select();
            });

            this.#elms.inputs.appendChild(input);
            this.#inputs.push(input);
        }
        this.dispatchEvent(new Event("change"));
    }
}

define("number-request-field", NumberRequestFieldElement);
